//
//  AppleLoginFlow.swift
//  casdon_swiftUI
//
//  Created by casdon on 2025/4/24.
//

import Combine

// 苹果登录流程
final class AppleLoginFlow {
    private let appleAuthStep: AppleAuthStep                // 第一步， 弹出授权窗口，获取用户授权
    private let cdAppleLoginStep:  CDAppleLoginStep         // 第二步，调用凯度云接口使用苹果返回的 token 和 id 等信息
    private let cdGetUserInfoStep: CDGetUserLoginInfoStep        // 第三步，调用凯度云服务获取用户信息
    private let tuyaLoginPwdStep: TuyaLoginPwdStep          // 第三步，调用涂鸦的账号密码登录

    let errorRedirectSubject: PassthroughSubject<Int, Never>?
    let bindAccountSubject:PassthroughSubject<Bool, Never>?
    
    init(errorRedirectSubject: PassthroughSubject<Int, Never>,
         bindAccountSubject: PassthroughSubject<Bool, Never>) {
        appleAuthStep = AppleAuthStep()
        cdAppleLoginStep = CDAppleLoginStep()
        tuyaLoginPwdStep = TuyaLoginPwdStep()
        cdGetUserInfoStep = CDGetUserLoginInfoStep()
        self.errorRedirectSubject = errorRedirectSubject
        self.bindAccountSubject = bindAccountSubject
    }
    
    func start() -> AnyPublisher<Void, Error> {
        appleAuthStep.execute(.init())
            .flatMap { [weak self] authResult -> AnyPublisher<AuthAPI.AppleLogin.Response, Error> in
                            guard let self = self else {
                                return Fail(error: FlowError.stepMissing).eraseToAnyPublisher()
                            }

                            return self.cdAppleLoginStep.execute(.init(userId: authResult.userId, authcode: authResult.authCode))
                                .catch { [weak self] error -> AnyPublisher<AuthAPI.AppleLogin.Response, Error> in
                                    // 通知外部发生错误，弹窗
                                     let nsError = error as NSError
                                    if nsError.code == 10012
                                    {
                                        self?.errorRedirectSubject?.send(nsError.code)
                                        return self?.bindAccountSubject?
                                            .prefix(1) // 只响应用户一次选择
                                            .flatMap { isAgree in
                                                if isAgree {
                                                    // 同意绑定
                                                    return self!.cdAppleLoginStep.execute(.init(userId: authResult.userId, authcode: authResult.authCode))
                                                }else
                                                {
                                                    // 拒绝绑定，则失败
                                                    return Fail(error: FlowError.stepMissing).eraseToAnyPublisher()
                                                }
                                            }
                                            .eraseToAnyPublisher() ?? Fail(error: FlowError.stepMissing).eraseToAnyPublisher()
                                    }
                                    return self!.cdAppleLoginStep.execute(.init(userId: authResult.userId, authcode: authResult.authCode))
                                }
                                .eraseToAnyPublisher()
                        }
            .flatMap { [weak self] response -> AnyPublisher<AuthAPI.UserLogInInfo.Response, Error> in
                        AuthManager.shared.saveToken(response.access_token)
                return self?.cdGetUserInfoStep.execute(.init()) ?? Fail(error: FlowError.stepMissing).eraseToAnyPublisher()
            }
            .flatMap { [weak self] userInfo -> AnyPublisher<Void, Error> in
                return self?.tuyaLoginPwdStep.execute(.init(account: userInfo.userName, password: userInfo.password)) ?? Fail(error: FlowError.stepMissing).eraseToAnyPublisher()
            }.eraseToAnyPublisher()
    }
}
